<template>
  <div class="meeting-room-scheduler">
    <div class="scheduler-container">
      <header>
        <h1>{{ roomInfo.name }}</h1>
        <div class="room-info">
          <div>
            可容纳人数：
            <span>{{ roomInfo.capacity }}人</span>
          </div>
          <div>
            内部设施：
            <span>{{ roomInfo.facilities.join('、') }}</span>
          </div>
        </div>
      </header>

      <div class="timeline-container">
        <div class="time-header">
          <div class="day-label-placeholder"></div>
          <div class="time-markers">
            <div
              v-for="(time, index) in timeSlots"
              :key="time"
              class="time-marker"
            >
              <span>{{ index % 2 === 0 ? formatTime(time) : '' }}</span>
            </div>
          </div>
        </div>

        <div
          class="timeline"
          ref="timelineRef"
          @mousemove="handleMouseMove"
          @mouseup="handleMouseUp"
          @mouseleave="handleMouseUp"
        >
          <div
            v-for="(day, dayIndex) in days"
            :key="dayIndex"
            class="day-row"
            @mouseenter="startHoverTimer(dayIndex)"
            @mouseleave="clearHoverTimer"
          >
            <div class="day-label">
              <span>{{ day.date }}</span>
              <span>{{ day.dayOfWeek }}</span>
            </div>
            <div class="time-slots">
              <n-tooltip
                :show="showTooltip && hoveredDay === dayIndex"
                trigger="hover"
                placement="bottom"
              >
                <template #trigger>
                  <div class="time-slots-wrapper">
                    <template
                      v-for="(time, timeIndex) in timeSlots"
                      :key="timeIndex"
                    >
                      <div
                        class="time-slot"
                        :class="{
                          selected: isSlotSelected(dayIndex, timeIndex),
                          'not-selectable': !isSlotSelectable(dayIndex, timeIndex)
                        }"
                        @mousedown="handleSlotMouseDown(dayIndex, timeIndex, $event)"
                      ></div>
                    </template>
                  </div>
                </template>
                <span>按住左键并拖动可选择多个时间段</span>
              </n-tooltip>
              <n-tooltip
                v-for="slot in day.timeSlots"
                :key="slot.id"
                :to="'body'"
                placement="top"
              >
                <template #trigger>
                  <div
                    class="meeting-block"
                    :class="getSlotClass(slot)"
                    :style="getSlotStyle(slot)"
                    :data-username="slot.userName"
                  >
                    <span v-if="getSlotStyle(slot).showTitle">{{ slot.title }}</span>
                  </div>
                </template>
                <span>{{ slot.title }}</span>
              </n-tooltip>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { NTooltip } from 'naive-ui'
import type { TimeSlot, Day, RoomInfo } from '@/types/interfaces'
import dayjs from 'dayjs'
import { useSelectionStore } from '@/stores/selectionStore'

const props = defineProps<{
  roomInfo: RoomInfo
  days: Day[]
  roomReservations: any[] // 新增：特定会议室的预定信息
}>()

const days = computed(() => {
  return props.days.map((day) => ({
    ...day,
    timeSlots: props.roomReservations
      .filter((reservation) => {
        const reservationDate = dayjs(reservation.startTime).format('YYYY-MM-DD')
        return reservationDate === day.fullDate
      })
      .map((reservation) => ({
        id: `${props.roomInfo.id}-${dayjs(reservation.startTime).valueOf()}`,
        start: new Date(reservation.startTime),
        end: new Date(reservation.endTime),
        title: reservation.content,
        type: reservation.type, // 假设 API 返回了 type 字段，否则需要根据实际情况判断，
        userName: reservation.userName
      }))
  }))
})

const emit = defineEmits<{
  (
    e: 'selectionMade',
    selection: {
      roomId: string
      start: Date
      end: Date
      roomName: string
      facilities: string
    } | null
  ): void
}>()

const selectionStore = useSelectionStore()

const timelineRef = ref<HTMLDivElement | null>(null)
const isDragging = ref(false)
const selectionStart = ref<{ day: number; time: number } | null>(null)
const selectionEnd = ref<{ day: number; time: number } | null>(null)

const timeSlots = computed(() => {
  const slots = []
  for (let hour = 8; hour <= 22; hour++) {
    slots.push(hour * 100)
    if (hour < 22) {
      slots.push(hour * 100 + 30)
    }
  }
  return slots
})

const formatTime = (time: number): string => {
  const hour = Math.floor(time / 100)
  const minute = time % 100
  return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
}

const getSlotClass = (slot: TimeSlot): string => {
  return slot.type === 'booked' ? 'booked' : 'my-booking'
}

const getSlotStyle = (slot: TimeSlot) => {
  const startTime = slot.start.getHours() * 100 + slot.start.getMinutes()
  const endTime = slot.end.getHours() * 100 + slot.end.getMinutes()
  const startIndex = timeSlots.value.indexOf(startTime)
  const endIndex = timeSlots.value.indexOf(endTime)
  const totalSlots = timeSlots.value.length

  const durationInHours = (slot.end.getTime() - slot.start.getTime()) / (1000 * 60 * 60)
  const showTitle = durationInHours > 1

  return {
    left: `${(startIndex / totalSlots) * 100}%`,
    width: `${((endIndex - startIndex) / totalSlots) * 100}%`,
    showTitle,
    durationInHours,
    content: slot.userName // 使用 userName 作为 content
  }
}
const hoveredDay = ref<number | null>(null)
const showTooltip = ref(false)
let hoverTimer: number | null = null

const startHoverTimer = (dayIndex: number) => {
  hoveredDay.value = dayIndex
  clearHoverTimer()
  hoverTimer = window.setTimeout(() => {
    showTooltip.value = true
  }, 1000)
}

const clearHoverTimer = () => {
  if (hoverTimer !== null) {
    clearTimeout(hoverTimer)
    hoverTimer = null
  }
  showTooltip.value = false
}

watch(
  () => selectionStore.selectedRoomId,
  (newRoomId) => {
    if (newRoomId !== props.roomInfo.id) {
      clearSelection()
    }
  }
)
const clearSelection = () => {
  selectionStart.value = null
  selectionEnd.value = null
  emit('selectionMade', null)
}

const isSlotSelectable = (dayIndex: number, timeIndex: number) => {
  const currentTime = new Date()
  const slotTime = new Date(props.days[dayIndex].fullDate)
  slotTime.setHours(Math.floor(timeSlots.value[timeIndex] / 100))
  slotTime.setMinutes(timeSlots.value[timeIndex] % 100)

  // 添加30分钟
  const minSelectableTime = new Date(currentTime.getTime() + 30 * 60000)

  return slotTime > minSelectableTime
}
// const isSlotSelectable = (dayIndex: number, timeIndex: number) => {
//   const currentTime = new Date()
//   const slotTime = new Date(props.days[dayIndex].fullDate)
//   slotTime.setHours(Math.floor(timeSlots.value[timeIndex] / 100))
//   slotTime.setMinutes(timeSlots.value[timeIndex] % 100)

//   // 添加30分钟
//   const minSelectableTime = new Date(currentTime.getTime() + 30 * 60000)

//   // 禁止选择最后一个格子（18:00）
//   const isLastSlot = timeIndex === timeSlots.value.length - 1

//   return slotTime > minSelectableTime && !isLastSlot
// }

const handleSlotMouseDown = (dayIndex: number, timeIndex: number, event: MouseEvent) => {
  event.preventDefault()
  const target = event.target as HTMLElement
  if (target.classList.contains('time-slot') && isSlotSelectable(dayIndex, timeIndex)) {
    isDragging.value = true
    clearSelection()
    selectionStart.value = { day: dayIndex, time: timeIndex }
    selectionEnd.value = { day: dayIndex, time: timeIndex }
    selectionStore.selectedRoomId = props.roomInfo.id
  }
}

const isTimeSlotAvailable = (dayIndex: number, timeIndex: number) => {
  const day = days.value[dayIndex]
  const slotTime = new Date(day.fullDate)
  slotTime.setHours(Math.floor(timeSlots.value[timeIndex] / 100))
  slotTime.setMinutes(timeSlots.value[timeIndex] % 100)

  return !day.timeSlots.some((slot) => slotTime >= slot.start && slotTime < slot.end)
}

const handleMouseMove = (e: MouseEvent) => {
  if (isDragging.value && timelineRef.value && selectionStart.value) {
    const rect = timelineRef.value.getBoundingClientRect()
    const x = e.clientX - rect.left
    const y = e.clientY - rect.top
    const dayHeight = rect.height / props.days.length
    const timeWidth = (rect.width - 219) / timeSlots.value.length

    const dayIndex = Math.floor(y / dayHeight)
    const timeIndex = Math.floor((x - 219) / timeWidth)

    if (timeIndex >= 0 && timeIndex < timeSlots.value.length) {
      let newEndTime = timeIndex

      // 检查从开始到当前鼠标位置的所有时间段
      const startTime = Math.min(selectionStart.value.time, timeIndex)
      const endTime = Math.max(selectionStart.value.time, timeIndex)

      for (let i = startTime; i <= endTime; i++) {
        if (!isTimeSlotAvailable(dayIndex, i) || !isSlotSelectable(dayIndex, i)) {
          // 如果遇到不可用的时间段，就停在前一个可用的时间段
          newEndTime = i - 1
          break
        }
      }

      selectionEnd.value = {
        day: selectionStart.value.day,
        time: newEndTime
      }
    }
  }
}

const handleMouseUp = () => {
  if (isDragging.value && selectionStart.value && selectionEnd.value) {
    const selection = calculateSelection(selectionStart.value, selectionEnd.value)
    emit('selectionMade', selection)
  }
  isDragging.value = false
}

const calculateSelection = (
  start: { day: number; time: number },
  end: { day: number; time: number }
) => {
  const startTime = Math.min(start.time, end.time)
  const endTime = Math.max(start.time, end.time)
  const selectedDay = props.days[start.day]

  return {
    roomId: props.roomInfo.id,
    roomName: props.roomInfo.name,
    facilities: props.roomInfo.facilities.join('、'),
    start: new Date(`${selectedDay.fullDate}T${formatTime(timeSlots.value[startTime])}:00`),
    end: new Date(`${selectedDay.fullDate}T${formatTime(timeSlots.value[endTime + 1] || 2200)}:00`)
  }
}

const isSlotSelected = (dayIndex: number, timeIndex: number) => {
  if (!selectionStart.value || !selectionEnd.value) return false
  if (!isSlotSelectable(dayIndex, timeIndex) || !isTimeSlotAvailable(dayIndex, timeIndex))
    return false

  const startTime = Math.min(selectionStart.value.time, selectionEnd.value.time)
  const endTime = Math.max(selectionStart.value.time, selectionEnd.value.time)

  return dayIndex === selectionStart.value.day && timeIndex >= startTime && timeIndex <= endTime
}
</script>

<style lang="scss" scoped>
.meeting-room-scheduler {
  width: 100%;
  margin: 0 auto;
}

.scheduler-container {
  background: #e1e1e1;
  padding: 20px;
}

header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;

  h1 {
    position: relative;
    display: flex;
    align-items: center;
    color: #1d2129;
    font-size: 20px;
    font-weight: 500;
    line-height: 34px; /* 170% */
    &:before {
      content: '';
      width: 4px;
      height: 18px;
      margin-right: 7px;
      border-radius: 2.5px;
      background: #6cb187;
    }
  }

  .room-info {
    display: flex;
    gap: 40px;
    font-size: 16px;
    color: #4e5969;
    span {
      color: #00895b;
    }
  }
}

.timeline-container {
  position: relative;
  overflow-x: auto;
}

.time-header {
  display: flex;
  position: relative;
  margin-bottom: 5px;
}

.day-label-placeholder {
  // width: 219px;
  width: 160px;
  flex-shrink: 0;
}

.time-markers {
  display: flex;
  flex: 1;
  position: relative;
}

.time-marker {
  position: relative;
  flex: 1;
  height: 20px;

  span {
    position: absolute;
    left: 0;
    top: 0;
    transform: translateX(-50%) translateY(5px);
    color: #18181b;
    font-size: 12px;
    white-space: nowrap;
  }

  &::before {
    content: '';
    position: absolute;
    left: 0;
    bottom: -5px;
    height: 5px;
    width: 1px;
    background-color: #c9cdd4;
  }
}

.timeline {
  position: relative;
  background: #fff;
  box-shadow: 0px 3.5px 5.5px 0px rgba(0, 0, 0, 0.02);
}

.day-row {
  display: flex;
}

.day-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  // width: 219px;
  width: 160px;
  flex-shrink: 0;
  border: 1px solid #c9cdd4;
  // border-top: none;
  background: #ebeceb;
  color: #1d2129;
  font-size: 16px;
  font-weight: 500;
}

.time-slots {
  flex: 1;
  position: relative;
  height: 60px;
  display: flex;
}

.time-slot {
  flex: 1;
  background: #ebeceb;
  border: 1px solid #c9cdd4;
  border-left: none;
  // border-top: none;
  cursor: pointer;

  &:first-child {
    border-left: 1px solid #c9cdd4;
  }

  &.selected {
    background-color: #00895b;
    z-index: 1;
  }
  &.not-selectable {
    background-color: #d1d1d1;
    cursor: not-allowed;
  }
  // &:last-of-type {
  //   display: none;
  // }
}
:deep(.n-tooltip) {
  max-width: none;
}

// 其余样式保持不变

.meeting-block {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 8px;
  height: calc(100% - 2px);
  padding: 0px 16px;
  top: 1px;
  font-size: 18px;
  color: #1d2129;
  overflow: hidden;
  border-radius: 4px;
  z-index: 2; // 确保预定块在选中区域之上
  background: #fff;

  span {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  &.booked,
  &.my-booking {
    &::before {
      content: attr(data-username);
      display: flex;
      width: 52px;
      height: 32px;
      // margin: 0 8px;
      margin: 0 4px;
      justify-content: center;
      align-items: center;
      border-radius: 53px;
      font-size: 10px;
      color: #fff;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }

  &.booked::before {
    background: #86909c;
    // content: '已预定';
  }

  &.my-booking::before {
    background: #267df0;
    // content: '我预定';
  }

  // 添加这个新的样式规则
  &:not([style*='showTitle:true']) {
    justify-content: center;
    padding: 0;

    &::before {
      width: 52px;
      height: 32px;
      padding: 2px 8px;
      border-radius: 53px;
    }
  }
}
.time-slots-wrapper {
  display: flex;
  flex: 1;
  height: 100%;
}
</style>
